﻿using System;
namespace Fx.Extensions
{
    public enum FallThrough
    {
        /// <summary>
        /// indicates fall through
        /// </summary>
        Yes,
        /// <summary>
        /// indicates no fallthrough
        /// </summary>
        No
    }

    public static class SwitchExtensions
    {
        public static Switch Case<T>(this Switch s, Action<T> a) where T : class
        {
            return Case(s, o => true, a, FallThrough.No);
        }

        public static Switch Case<T>(this Switch s, Action<T> a, FallThrough fallThrough) where T : class
        {
            return Case(s, o => true, a, fallThrough);
        }

        public static Switch Case<T>(this Switch s, Func<T, bool> c, Action<T> a) where T : class
        {
            return Case(s, c, a, FallThrough.No);
        }

        public static Switch Case<T>(this Switch s, Func<T, bool> c, Action<T> a, FallThrough fallThrough) where T : class
        {
            if (s == null)
            {
                return null;
            }
            var t = s.Object as T;
            if (t != null)
            {
                if (c(t))
                {
                    a(t);
                    return fallThrough == FallThrough.Yes ? s : null;
                }
            }

            return s;
        }

        public static void Default(this Switch s, Action<object> a)
        {
            if (s != null)
            {
                a(s.Object);
            }
        }

        public static void Default(this Switch s, Action a)
        {
            if (s != null)
            {
                a();
            }
        }
    }

    public class Switch
    {
        public Switch(object o)
        {
            Object = o;
        }

        public object Object { get; private set; }
    }
}
